<?php

namespace Sharks\Core\Support\Bag;

use Sharks\Core\Support\Base\Argument;
use Sharks\Core\Support\Base\DefValue;
use Sharks\Core\Support\Base\Precondition;

class ParameterBag implements Bag {
    private $data;

    public function __construct(array &$data = array()) {
        if (is_null($data)) {
            $data = array();
        }
        $this->data = &$data;
    }

    /**
     * 取值
     * @param $key
     * @param null $default
     * @return mixed
     */
    public function get($key, $default = null) {
        if (isset($this->data[$key])) {
            return $this->data[$key];
        }
        return $default;
    }

    /**
     * 取不到值就抛出异常
     * @param $key
     * @return array|null
     */
    public function getOrFail($key) {
        $result = $this->get($key);
        Precondition::checkNotNull($result, '错误的属性值 %s', $key);
        return $result;
    }

    /**
     * 确认数据包中属性值是否存在
     * @param $key 属性名称
     * @return bool
     */
    public function has($key) {
        return isset($this->data[$key]) && !is_null($this->data[$key]) && !empty($this->data[$key]);
    }
    
    /**
     * 判断是否为空。注意，如果$key不存在，返回true。
     * @param unknown $key
     * @return boolean
     */
    public function isEmpty($key) {
    	if (!$this->has($key)) {
    		return true;
    	}
    	return Argument::isEmpty($this->data[$key]);
    }
    
    public function isNotEmpty($key) {
    	return !$this->isEmpty($key);
    }

    /**
     * 移除某名称的值
     * @param $key
     */
    public function forget($key) {
        if ($this->has($key)) {
            $result = $this->data[$key];
            unset($this->data[$key]);
            return $result;
        }
        return null;
    }

    /**
     * 设置某名称的值
     * @param $key
     * @param $value
     * @return mixed
     */
    public function put($key, $value) {
        $this->data[$key] = $value;
    }

    /**
     * 增加数组数据
     * @param array $data
     */
    public function add(array $data = array()) {
        foreach ($data as $k => $d) {
            $this->data[$k] = $d;
        }
    }

    /**
     * 原始数据,所有值
     * @return array
     */
    public function all() {
        return $this->data;
    }

    public function size() {
        return count($this->data);
    }
}